package com.shanxia.codec.cmd;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.DecodeEnum;
import lombok.Data;

import static com.shanxia.codec.Decoder.*;

/**
 * S -> C
 * 后台服务器下发充电桩控制命令
 * 后台服务器向充电桩控制命令
 */
@Data
public class Cmd5 extends ProtocolDataBase {

    public static final int MIN_SIZE = 12;

    private int v1;
    private int v2;
    private int pilePort;                    // 充电枪口: 只有一机一桩此参数可为 0，多枪编号从 1 开始
    private int paramAddr;                   // 启始命令地址
    private int paramNum;                    // 命令个数
    private int paramLength;                 // 命令参数长度
    private int data;                        // 设置数据

    public Cmd5(){
        super.setCmd(5);
    }

    public static Cmd5 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd5 cmd = new Cmd5();
        cmd.copyDataFrom(protocolDataBase);
        byte[] dataField = protocolDataBase.getDataField();
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 1字节充电枪口
        cmd.pilePort = getUint8(dataField[offset++]);
        // 4字节启始命令地址
        cmd.paramAddr = bytesToIntLittle(dataField, offset);
        offset += 4;
        // 1字节命令个数
        cmd.paramNum = getUint8(dataField[offset++]);
        // 2字节 命令参数长度
        cmd.paramLength = getUint16(dataField, offset);
        offset += 2;
        // N（4）字节
        cmd.data = getInt32(dataField, offset);
        return cmd;
    }

    @Override
    public byte[] getDataField() {
        int offset = 0;
        byte[] buf = new byte[MIN_SIZE + this.paramLength];
        getBytesAsUint16(buf, offset, this.v1);
        offset += 2;
        getBytesAsUint16(buf, offset, this.v2);
        offset += 2;
        // 1字节充电枪口
        buf[offset++] = (byte) this.pilePort;
        // 4字节启始命令地址
        intToBytesLittle(buf, offset, this.paramAddr);
        offset += 4;
        // 1字节命令个数
        buf[offset++] = (byte) paramNum;
        // 命令参数长度
        getBytesAsUint16(buf, offset, this.paramLength);
        offset += 4;
        // 4字节命令参数
        // 数据域转换得根据不同得结果来转换
        intToBytesLittle(buf, offset, data);
        return buf;
    }
}